﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

using Rockfan.Framework;
using Rockfan.Framework.Audio;
using Rockfan.Framework.Entities;
using Rockfan.Framework.Entities.Interfaces;
using Rockfan.Framework.Graphics;

namespace Rockfan.Framework.Entities
{
    public abstract class Playerboard : IDrawableEntity, IDestroyable
    {
        #region Properties

        public float TimeCreated { get; private set; }
        public PlayerIndex PlayerIndex { get; private set; }

        public bool EnableUpdates { get; set; }
        public bool EnableDrawing { get; set; }
        public bool IsLoaded { get; private set; }

        string IEntity.Name
        {
            get { return string.Empty; }
        }

        float IDrawableEntity.X { get { return 0.0f; } set { } }

        float IDrawableEntity.Y { get { return 0.0f; } set { } }

        float IDrawableEntity.Z { get { return 0.0f; } set { } }

        #endregion

        #region Methods

        public Playerboard(PlayerIndex index, NoteTracks chart)
        {
            this.Chart = chart;
            this.PlayerIndex = index;
            this.TimeCreated = EngineServices.TotalGameTime;
            this.Camera = new Camera();            
            this.SpriteEffect = new SpriteEffect(EngineServices.GraphicsDevice);
            this.FretboardEffect = new FretboardEffect(EngineServices.GraphicsDevice);
        }
        
        public abstract void LoadContent();
        public abstract Task LoadContentAsync(ProgressChanged callback);

        public abstract void Start();
        public abstract void Finish();

        public abstract void SwapNotes(float delta);
        public abstract void UpdateBoardPosition(float delta);        
        public abstract void ChangeDifficulty(Difficulty difficulty);

        protected abstract void Update(float delta);
        protected abstract void Draw();

        protected abstract void Destroy();

        #region Interface Implementations

        void IDrawableEntity.Draw(Effect effect)
        {
            if (this.EnableDrawing)
                this.Draw();
        }

        bool IDrawableEntity.GetIsInView(BoundingFrustum frustum)
        {
            return true;
        }

        bool IDrawableEntity.GetIsInView(Matrix view, Matrix projection)
        {
            return true;
        }

        void IUpdateableEntity.Update(float delta)
        {
            if (EnableUpdates)
                this.Update(delta);
        }

        void IDestroyable.Destroy()
        {
            this.Destroy();
        }

        #endregion        

        #endregion

        protected Camera Camera;
        protected NoteTracks Chart;
        protected SpriteEffect SpriteEffect;
        protected FretboardEffect FretboardEffect;
    }
}
